<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <title>抽奖页面</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        html,
        body {
            width: 100%;
            height: 100%;
        }

        body {
            text-align: center;
            background: url("./pic/bg.png") no-repeat;
            overflow: hidden;
            background-size: 100% 100%;
            font-weight: bold;
            color: #D40000;
        }

        #container {
            min-width: 1000px;
            min-height: 700px;
        }

        #title {
            font-size: 100px;
            margin-top: 80px;
        }

        #disc {
            font-size: 40px;
            margin: 10px 0;
        }

        #image {
            margin-top: 20px;
            max-height: 280px;
            border: 1px solid #E23540FF;
            border-radius: 20px;
        }

        #list {
            margin: 0 auto;
            max-width: 800px;
        }

        #list span {
            display: inline-block;
            width: 160px;
            font-size: 36px;
            margin-top: 8px;
        }

        .records-item {
            text-align: center;
            cursor: pointer;
            padding: 20px;
            transition: background-color 0.3s;
            font-size: 20px;
        }

        .opt-box {
            display: flex;
            align-items: center;
            justify-content: center;
            margin-top: 30px;
        }

        .opt-box .btn {
            width: 120px;
            height: 32px;
            display: flex;
            align-items: center;
            justify-content: center;
            border: 2px solid #D40000;
            margin-inline: 18px;
            cursor: pointer;
            border-radius: 4px;
            font-weight: normal;
            font-size: 15px;
        }

        .opt-box .btn:hover {
            background-color: #D40000;
            color: #fff;
        }
    </style>
</head>

<body>
    <div id="container">
        <div id="title"></div>
        <div id="disc"></div>
        <img id="image" />
        <div id="list"></div>
        <div class="opt-box">
            <span class="btn pre-btn" onclick="previousStep()">查看上一奖项</span>
            <span class="btn next-btn" onclick="nextStep()">开始抽奖</span>
        </div>
    </div>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="./js/comment.js"></script>
    <script>

        var params = new URLSearchParams(window.location.search);
        var activityId = params.get('activityId');
        var valid = params.get('valid');
        var userToken = localStorage.getItem("user_token");


        // 获取网页上通过id为disc、image和list的DOM元素的引用。
        var disc = document.getElementById('disc')
        var image = document.getElementById('image')
        var list = document.getElementById('list')

        // 奖品列表
        var steps = null
        // 抽到第几个了
        var step = 0
        // 人员列表
        var names = null
        // 正在做什么
        var state = ''

        // 将活动信息放入title中
        document.addEventListener('DOMContentLoaded', function () {
            var titleDiv = document.getElementById('title');
            var activityName = params.get('activityName');
            titleDiv.textContent = activityName;
        });

        // 用于将时间进行格式化
        function formatDate(dateString) {
            var date = new Date(dateString);
            var hour = ('0' + date.getHours()).slice(-2);
            var minute = ('0' + date.getMinutes()).slice(-2);
            var second = ('0' + date.getSeconds()).slice(-2);
            // 构建格式化的日期字符串
            return hour + ':' + minute + ':' + second;
        }

        // showPic函数用于显示图片和奖品信息。
        // 它将data.disc设置为disc元素的innerHTML，将data.image设置为image元素的src属性，然后显示图片并隐藏列表。
        function showPic(data) {
            disc.innerHTML = data.prizeTierName + ' ' + data.name + ' ' + data.prizeAmount + '份'
            image.src = data.imageUrl ? data.imageUrl : '/pic/defaultPrizeImg.png'
            image.style.display = 'inline'
            list.style.display = 'none'
            while (list.hasChildNodes()) {
                list.removeChild(list.firstChild)
            }
        }

        // 查询中奖记录
        function showRecords() {
            disc.innerHTML = "中奖名单"
            image.style.display = 'none'
            list.style.display = 'block'
            while (list.hasChildNodes()) {
                list.removeChild(list.firstChild)
            }
            $.ajax({
                url: '/draw/getWinnerRecord',
                type: 'POST',
                dataType: 'json',
                contentType: 'application/json',
                data: JSON.stringify({ activityId: activityId }),
                success: function (result) {
                    if (result.code != 200) {
                        alert("查询中奖记录失败！" + result.msg);
                    } else {
                        var records = result.data
                        list.className = "records-item"
                        for (var i = 0; i < records.length; ++i) {
                            var item = document.createElement('div')
                            item.textContent = formatDate(records[i].winningTime) + ' '
                                + records[i].winnerName + ' '
                                + records[i].prizeName + ' '
                                + records[i].prizeTier + ' '
                            list.appendChild(item)
                        }

                        // 分享链接
                        // 检查是否已经有分享按钮，如果没有则创建
                        var optBox = document.querySelector('.opt-box');
                        var existingBtn = optBox.querySelector('.btn.copy-btn');
                        if (!existingBtn) {
                            var newBtn = document.createElement('span');
                            newBtn.className = 'btn copy-btn';
                            // 设置点击事件处理函数
                            newBtn.onclick = function () {
                                // 创建URL对象
                                var currentUrl = new URL(window.location);
                                // 创建URLSearchParams对象
                                var searchParams = currentUrl.searchParams;
                                // 更新参数
                                searchParams.delete('valid');
                                searchParams.append('valid', false);
                                // 防止分享再分享，拼接多个参数
                                searchParams.delete('hideButton');
                                searchParams.append('hideButton', true);
                                // 更新URL对象的搜索字符串
                                currentUrl.search = searchParams.toString();
                                // 获取当前页面的URL
                                var url = currentUrl;
                                // 执行复制操作
                                copyToClipboard(url);
                            };
                            // 设置span元素的文本内容
                            newBtn.textContent = '分享结果';
                            // 将新的span元素添加到.opt-box容器中
                            optBox.appendChild(newBtn);
                        }

                        // 是否隐藏按钮
                        var hideButton = params.get('hideButton');
                        if ((hideButton == null && valid === 'false')
                            || hideButton === 'true') {
                            // 隐藏所有元素
                            var buttons = document.querySelectorAll('.btn.pre-btn, .btn.next-btn');
                            buttons.forEach(function (button) {
                                button.style.display = 'none';
                            });
                        }
                    }
                }
            });
        }

        // 复制当前地址
        function copyToClipboard(textToCopy) {
            // navigator clipboard 需要https等安全上下文
            if (navigator.clipboard && window.isSecureContext) {
                // navigator clipboard 向剪贴板写文本
                return navigator.clipboard.writeText(textToCopy)
                    .then(() => { alert("链接已复制到剪贴板"); });
            } else {
                // 创建text area
                let textArea = document.createElement("textarea");
                textArea.value = textToCopy;
                // 使text area不在viewport，同时设置不可见
                textArea.style.position = "absolute";
                textArea.style.opacity = 0;
                textArea.style.left = "-999999px";
                textArea.style.top = "-999999px";
                document.body.appendChild(textArea);
                textArea.focus();
                textArea.select();
                return new Promise((res, rej) => {
                    // 执行复制命令并移除文本框
                    document.execCommand('copy') ? res() : rej();
                    textArea.remove();
                    alert("链接已复制到剪贴板");
                });
            }
        }

        // showBlink函数用于显示闪烁的文字。
        // 它首先设置奖品信息，隐藏图片，显示列表，然后创建与data.count相等数量的span元素。
        function showBlink(data) {
            disc.innerHTML = data.prizeTierName + ' ' + data.name + ' ' + data.prizeAmount + '份'
            image.style.display = 'none'
            list.style.display = 'block'
            var spans = []
            for (var i = 0; i < data.prizeAmount; ++i) {
                var span = document.createElement('span')
                list.appendChild(span)
                spans.push(span)
            }

            // doBlink函数用于实现文字的闪烁效果，通过window.requestAnimationFrame来循环调用。
            function doBlink() {
                if (state == 'showBlink') {
                    // Math.random() 生成一个 [0, 1) 范围内的伪随机数，
                    // 所以表达式的结果将在 (-0.5, 0.5] 范围内，这会导致 names 数组的元素随机排序。
                    names.sort(function (a, b) {
                        return 0.5 - Math.random()
                    })
                    // 只展示当前奖项个数的随机人名
                    for (var i = 0; i < data.prizeAmount; ++i) {
                        spans[i].innerHTML = names[i].userName
                    }
                    window.requestAnimationFrame(doBlink)
                }
            }

            // 告诉浏览器——你希望执行一个动画，并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
            window.requestAnimationFrame(doBlink)
        }

        // 直接展示最终的中奖人员信息
        function showWinnerListWithPrize(data) {
            $.ajax({
                url: '/draw/getWinnerRecord',
                type: 'POST',
                dataType: 'json',
                contentType: 'application/json',
                data: JSON.stringify({ activityId: activityId, prizeId: data.prizeId }),
                success: function (result) {
                    if (result.code != 200) {
                        alert("查询中奖记录失败！" + result.msg);
                    } else {
                        var luckRecords = result.data
                        // 从names中移除幸运儿
                        var luck = []
                        // 获得需要删除的用户id
                        var needRemoves = luckRecords.map(function (luckRecord) {
                            return luckRecord.winnerId;
                        });
                        // 从names中移除包含在luckRecords中的name对应的元素
                        for (var i = 0; i < names.length; i++) {
                            if (needRemoves.includes(names[i].userId)) {
                                var tmp = names.splice(i, 1)  // 移除当前项，并更新索引i，因为后面的项会向前移动
                                luck = luck.concat(tmp)
                                console.log("tmp" + JSON.stringify(tmp))
                                i--  // 减1以确保索引i仍然指向当前的项
                            }
                        }
                        // 只存放当前奖项的人员信息，下次抽奖会被覆盖
                        data.list = luck.map(x => x)
                        for (var i = 0; i < data.list.length; ++i) {
                            var span = document.createElement('span')
                            span.innerHTML = data.list[i].userName
                            list.appendChild(span)
                        }
                    }
                }
            });
        }

        // showList函数用于显示静态的文字列表。它设置奖品信息，隐藏图片，显示列表，并将data.list中的数据添加到列表中。
        function showList(data) {
            disc.innerHTML = data.prizeTierName + ' ' + data.name + ' ' + data.prizeAmount + '份'
            image.style.display = 'none'
            list.style.display = 'block'
            while (list.hasChildNodes()) {
                list.removeChild(list.firstChild)
            }

            // data.list是前端保存的临时数据，若当前抽奖页刷新，则数据丢失
            // 因此判断一下是否为空，为空需要查询后端
            data.list = data.list || []
            if (data.list.length > 0) {
                for (var i = 0; i < data.list.length; ++i) {
                    var span = document.createElement('span')
                    span.innerHTML = data.list[i].userName
                    list.appendChild(span)
                }
            } else {
                showWinnerListWithPrize(data)
            }
        }

        // 这是改变next-btn按钮文本的函数
        function changeNextButtonText(text) {
            var nextButton = document.querySelector('.btn.next-btn');
            nextButton.textContent = text;
        }

        // 构造某个奖品的获奖人员信息并存储到后端
        function saveLuck() {
            var data = steps[step]

            var luckUserList = []
            for (var i = 0; i < data.list.length; ++i) {
                luckUserList.push({
                    userId: data.list[i].userId,
                    userName: data.list[i].userName
                })
            }

            var drawPrizesData = {
                activityId: activityId,
                prizeId: data.prizeId,
                winningTime: new Date(),
                winnerList: luckUserList
            };


            // 发送AJAX请求
            $.ajax({
                url: '/draw/prize',
                type: 'POST',
                dataType: 'json',
                contentType: 'application/json',
                data: JSON.stringify(drawPrizesData),
                success: function (result) {
                    if (result.code != 200) {
                        alert("抽奖失败！" + result.msg);
                    }
                },
                error: function (err) {
                    console.log(err);
                    if (err != null && err.status == 401) {
                        alert("用户未登录, 即将跳转到登录页!");
                        // 已经被拦截器拦截了, 未登录
                        location.href = "/blogin.html";
                    }
                }
            });
        }

        // nextStep函数用于根据当前状态显示下一个步骤的内容。
        // 它根据state的值和data.list的长度来决定是显示图片、闪烁文字还是静态文字列表，并更新step和state。
        function nextStep() {
            var data = steps[step]
            console.log("steps[" + step + "]:" + JSON.stringify(data))
            if (state == 'showPic') {
                if (data.valid) {
                    // 还没抽：抽奖
                    state = 'showBlink'
                    showBlink(data)
                    changeNextButtonText('点我确定')
                } else {
                    // 抽过了：展示
                    state = 'showList'
                    showList(data)
                    changeNextButtonText('已抽完，下一步')
                }
            } else if (state == 'showBlink') {
                // 从names中移除幸运儿，并将幸运儿存放起来
                var luck = names.splice(0, data.prizeAmount)
                // 只存放当前奖项的人员信息，下次抽奖会被覆盖
                data.list = luck.map(x => x)
                console.log("data.list:" + JSON.stringify(data.list))
                // 调用后端抽奖接口，保存中奖信息
                saveLuck()
                data.valid = false
                state = 'showList'
                showList(data)
                changeNextButtonText('已抽完，下一步')
            } else if (state == 'showList') {
                if (step < (steps.length - 1)) {
                    ++step
                    state = ''
                    nextStep()
                    changeNextButtonText('开始抽奖')
                } else {
                    // 抽奖结束，展示全量中奖列表
                    if (step == (steps.length - 1)) {
                        ++step
                    }
                    showRecords()
                    changeNextButtonText('已全部抽完')
                }
            } else {
                state = 'showPic'
                showPic(data)
                changeNextButtonText('开始抽奖')
            }
        }

        // previousStep函数用于返回到上一个步骤。如果当前步骤不是第一个步骤，则减少step的值，然后调用nextStep函数。
        function previousStep() {
            if (step > 0) {
                --step
            }
            state = ''
            nextStep()
        }

        // 一上来对身份信息活动信息进行校验
        function drawPage() {
            // 判断活动是否有效:进行中
            if (valid == "true") {
                // 判断是用户还是管理员，只有管理员有权限抽奖
                var identity = localStorage.getItem("user_identity");
                if (identity == "ADMIN") {
                    // 在页面加载完成后，调用reloadConf函数并传入nextStep作为回调函数，以初始化页面显示。
                    reloadConf(nextStep)
                } else {
                    alert("抽奖未结束，由于您不是管理员，无权限限参与抽奖。请耐心等待抽奖结束后查看中奖名单");
                }
            } else {
                showRecords()
            }
        }

        // reloadConf函数用于重新加载配置文件。
        // 如果提供了回调函数func，则在文件读取完成后调用它。
        function reloadConf(func) {
            // 发送AJAX请求
            $.ajax({
                url: '/activity/getActivityDetail',
                type: 'GET',
                data: { activityId: activityId },
                dataType: 'json',
                success: function (result) {
                    if (result.code != 200) {
                        alert("获取活动详情失败！" + result.msg);
                    } else {
                        names = result.data.users;
                        steps = result.data.prizes;
                        if (func) func();
                    }
                },
                error: function (err) {
                    console.log(err);
                    if (err != null && err.status == 401) {
                        alert("用户未登录, 即将跳转到登录页!");
                        // 已经被拦截器拦截了, 未登录
                        location.href = "/blogin.html";
                    }
                }
            });
        }

        // 抽奖页起始逻辑
        drawPage()
    </script>
</body>

</html>